<?php

namespace common\models\trade;

use Yii;

/**
 * This is the model class for table "{{%trade_order}}".
 *
 * @property int $id
 * @property string $trade_id 交易ID
 * @property string $original_no 原始交易号
 * @property string $paymode 交易支付方式
 * @property string $pay_type 交易类型
 * @property string $pay_no 支付订单号
 * @property string $currency 货币类型
 * @property string $pay 支付金额
 * @property string $pay_time 交易支付时间
 * @property int $balance 收支标识：-1支出，1收入
 * @property string $expire_time 交易过期时间
 * @property int $status 交易状态
 * @property string $created_at 创建时间
 * @property string $updated_at 更新时间
 */
class TradeOrder extends \common\db\ActiveRecord {

    use \common\traits\Constants;

    /**
     * 异常状态检测
     * 0未检测
     * 1无错误
     * -1异常
     */
    const ERRORSTATE_EXIST = -1;
    const ERRORSTATE_UNCHECK = 0;
    const ERRORSTATE_NONE = 1;
    const ERRORSTATE_TASK = 2;

    /**
     * 交易状态
     * @var STATUS_DEFAULT  0   默认状态
     * @var STATUS_SUCCESS  1   支付成功
     */
    const STATUS_DEFAULT = 0;
    const STATUS_SUCCESS = 1;

    /**
     * 订单支付方式
     * @var PAYMODE_WECHAT  wechat  微信支付
     * @var PAYMODE_ALIPAY  alipay  支付宝支付
     * @var PAYMODE_APPLE   apple   苹果支付
     * @var PAYMODE_CREDIT  credit  积分支付
     */
    const PAYMODE_WECHAT = 'wechat';
    const PAYMODE_ALIPAY = 'alipay';
    const PAYMODE_APPLE = 'apple';
    const PAYMODE_CREDIT = 'credit';

    /**
     * 交易收支类型
     * @var BALANCE_PAYMENT 1   支付
     * @var BALANCE_REFUND  -1  退款
     */
    const BALANCE_PAYMENT = 1;
    const BALANCE_REFUND = -1;

    /**
     * 货币类型
     * @var BALANCE_PAYMENT 1   支付
     * @var BALANCE_REFUND  -1  退款
     */
    const CURRENCY_CNY = 'CNY';
    const CURRENCY_CREDIT = 'CREDIT';

    /**
     * 支付对账状态
     * @var CHECK_STATUS_DEFAULT  0  未核对
     * @var CHECK_STATUS_SUCCESS  1  已核对
     */
    const CHECK_STATUS_DEFAULT = 0;
    const CHECK_STATUS_SUCCESS = 1;

    /**
     * @inheritdoc
     */
    public static function tableName() {
        return '{{%trade_order}}';
    }

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['trade_id', 'pay_time', 'balance', 'expire_time', 'status', 'created_at', 'updated_at'], 'integer'],
            [['paymode'], 'required'],
            [['pay'], 'number'],
            [['original_no', 'pay_type', 'pay_no'], 'string', 'max' => 32],
            [['currency'], 'string', 'max' => 16],
            [['mark'], 'string', 'max' => 255],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'id' => 'ID',
            'trade_id' => '交易ID',
            'original_no' => '原始交易号',
            'paymode' => '交易支付方式',
            'pay_type' => '交易类型',
            'pay_no' => '支付订单号',
            'currency' => '货币类型',
            'pay' => '支付金额',
            'pay_time' => '交易支付时间',
            'balance' => '收支标识',
            'expire_time' => '交易过期时间',
            'status' => '交易状态',
            'created_at' => '创建时间',
            'updated_at' => '更新时间',
            'mark' => '备注信息',
        ];
    }

    /**
     * Finds order by tradeno
     *
     * @param string $paymode
     * @return static|null
     */
    public function setPayType($paymode) {
        if ($paymode == self::PAYMODE_WECHAT) {
            $this->pay_type = 'APP';
        }
    }

    /**
     * Finds order by tradeno
     *
     * @param string $mark
     * @return static|null
     */
    public function setMark($mark) {
        $temp = '[' . date('Y-m-d H:i:s') . ']' . $mark;
        $this->mark .= $temp . "\n";
    }

    /**
     * Finds order by mch_no
     *
     * @param string $trade_no
     * @param string $paymode
     * @return static|null
     */
    public static function findByTn($trade_no, $paymode) {
        $tns = explode('R', $trade_no);
        if (count($tns) > 1) {
            return static::findOne(['original_no' => $tns[1], 'paymode' => $paymode, 'id' => $tns[0]]);
        }
        return static::findOne(['original_no' => $trade_no, 'paymode' => $paymode]);
    }

    /**
     * Find trade
     */
    public function getTrade() {
        return $this->hasOne(Trade::className(), ['id' => 'trade_id']);
    }

    /**
     * Find trade
     */
    public function getInverseOfTrade() {
        return $this->getTrade()->inverseOf('orders');
    }

    /**
     * Find trade
     */
    public function getPaymentTrade() {
        return $this->hasOne(Trade::className(), ['trade_no' => 'original_no'])->andWhere([
            'balance' => Trade::BALANCE_PAYMENT
        ]);
    }

    /**
     * 生成积分支付单号
     */
    public function generateCreditPn() {
        $format = 'YmdHisu';
        do {
            $utimestamp = microtime(true);
            $timestamp = floor($utimestamp);
            $milliseconds = round(($utimestamp - $timestamp) * 1000000);
            $date = date(preg_replace('`(?<!\\\\)u`', $milliseconds, $format), $timestamp);
            $pn = 'C' . str_pad($date, 20, 0, STR_PAD_RIGHT) . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
            $record = static::find()->where(['paymode' => static::PAYMODE_CREDIT, 'pay_no' => $pn])->exists();
        } while ($record);
        $this->paymode = static::PAYMODE_CREDIT;
        $this->currency = static::CURRENCY_CREDIT;
        $this->balance = static::BALANCE_PAYMENT;
        $this->pay_no = $pn;
        return $pn;
    }

    public function getExistRefund() {
        $res = static::findOne([
            'trade_id' => $this->trade_id,
            'paymode' => $this->paymode,
            'balance' => self::BALANCE_REFUND,
        ]);

        return $res ? true : false;
    }

}
